#define __ASSEMBLY__
#include "gpio.h"

void xs_setgpio_dir(int gpio_num, int direction)
{
	volatile int *regT;

	if(gpio_num < 32)
	{
		regT = (volatile int *)GPDR0;
		if(direction == GPIO_PIN_IN)
			*regT &= ~(1 << (gpio_num % 32));
		if(direction == GPIO_PIN_OUT)
			*regT |= (1 << (gpio_num % 32));
		return;
	}
	if(gpio_num < 64)
	{
		regT = (volatile int *)GPDR1;
		if(direction == GPIO_PIN_IN)
			*regT &= ~(1 << (gpio_num % 32));
		if(direction == GPIO_PIN_OUT)
			*regT |= (1 << (gpio_num % 32));
		return;
	}
	if(gpio_num < 96)
	{
		regT = (volatile int *)GPDR2;
		if(direction == GPIO_PIN_IN)
			*regT &= ~(1 << (gpio_num % 32));
		if(direction == GPIO_PIN_OUT)
			*regT |= (1 << (gpio_num % 32));
		return;
	}
	if(gpio_num <= 120)
	{
		regT = (volatile int *)GPDR3;
		if(direction == GPIO_PIN_IN)
			*regT &= ~(1 << (gpio_num % 32));
		if(direction == GPIO_PIN_OUT)
			*regT |= (1 << (gpio_num % 32));
		return;
	}
}
void xs_setgpio_outhigh(int gpio_num)
{
	volatile int *regT;

	if(gpio_num < 32)
	{
		regT = (volatile int *)GPSR0;
		*regT |= (1 << (gpio_num % 32));
		return;
	}
	if(gpio_num < 64)
	{
		regT = (volatile int *)GPSR1;
		*regT |= (1 << (gpio_num % 32));
		return;
	}
	if(gpio_num < 96)
	{
		regT = (volatile int *)GPSR2;
		*regT |= (1 << (gpio_num % 32));
		return;
	}
	if(gpio_num <= 120)
	{
		regT = (volatile int *)GPSR3;
		*regT |= (1 << (gpio_num % 32));
		return;
	}
}
void xs_setgpio_outlow(int gpio_num)
{
	volatile int *regT;

	if(gpio_num < 32)
	{
		regT = (volatile int *)GPCR0;
		*regT |= (1 << (gpio_num % 32));
		return;
	}
	if(gpio_num < 64)
	{
		regT = (volatile int *)GPCR1;
		*regT |= (1 << (gpio_num % 32));
		return;
	}
	if(gpio_num < 96)
	{
		regT = (volatile int *)GPCR2;
		*regT |= (1 << (gpio_num % 32));
		return;
	}
	if(gpio_num <= 120)
	{
		regT = (volatile int *)GPCR3;
		*regT |= (1 << (gpio_num % 32));
		return;
	}
}
void xs_setgpio_RER(int gpio_num, int isedge)
{
	volatile int *regT;

	if(gpio_num < 32)
	{
		regT = (volatile int *)GRER0;
		if(isedge == DISABLE_EDGE)
			*regT &= ~(1 << (gpio_num % 32));
		if(isedge == ENABLE_EDGE)
			*regT |= (1 << (gpio_num % 32));
		return;
	}
	if(gpio_num < 64)
	{
		regT = (volatile int *)GRER1;
		if(isedge == DISABLE_EDGE)
			*regT &= ~(1 << (gpio_num % 32));
		if(isedge == ENABLE_EDGE)
			*regT |= (1 << (gpio_num % 32));
		return;
	}
	if(gpio_num < 96)
	{
		regT = (volatile int *)GRER2;
		if(isedge == DISABLE_EDGE)
			*regT &= ~(1 << (gpio_num % 32));
		if(isedge == ENABLE_EDGE)
			*regT |= (1 << (gpio_num % 32));
		return;
	}
	if(gpio_num <= 120)
	{
		regT = (volatile int *)GRER3;
		if(isedge == DISABLE_EDGE)
			*regT &= ~(1 << (gpio_num % 32));
		if(isedge == ENABLE_EDGE)
			*regT |= (1 << (gpio_num % 32));
		return;
	}
}
void xs_setgpio_FER(int gpio_num, int isedge)
{
	volatile int *regT;

	if(gpio_num < 32)
	{
		regT = (volatile int *)GFER0;
		if(isedge == DISABLE_EDGE)
			*regT &= ~(1 << (gpio_num % 32));
		if(isedge == ENABLE_EDGE)
			*regT |= (1 << (gpio_num % 32));
		return;
	}
	if(gpio_num < 64)
	{
		regT = (volatile int *)GFER1;
		if(isedge == DISABLE_EDGE)
			*regT &= ~(1 << (gpio_num % 32));
		if(isedge == ENABLE_EDGE)
			*regT |= (1 << (gpio_num % 32));
		return;
	}
	if(gpio_num < 96)
	{
		regT = (volatile int *)GFER2;
		if(isedge == DISABLE_EDGE)
			*regT &= ~(1 << (gpio_num % 32));
		if(isedge == ENABLE_EDGE)
			*regT |= (1 << (gpio_num % 32));
		return;
	}
	if(gpio_num <= 120)
	{
		regT = (volatile int *)GFER3;
		if(isedge == DISABLE_EDGE)
			*regT &= ~(1 << (gpio_num % 32));
		if(isedge == ENABLE_EDGE)
			*regT |= (1 << (gpio_num % 32));
		return;
	}
}
void xs_setgpio_AFR(int gpio_num, int function)
{
	volatile int *regT;

	if(gpio_num < 16)
	{
		regT = (volatile int *)GAFR0_L;
		if(function == GPIO_AS_GPIO)
		{

			*regT &= ~((1 << ((gpio_num % 16) * 2)) | (1 << ((gpio_num % 16) * 2 + 1)));
			//*regT |= (11 << ((gpio_num % 16) * 2));
		}
		if(function == GPIO_AS_AF1)
		{

			*regT &= ~(1 << ((gpio_num % 16) * 2 + 1));
			*regT |= (1 << ((gpio_num % 16) * 2));
		}
		if(function == GPIO_AS_AF2)
		{

			*regT &= ~(1 << ((gpio_num % 16) * 2));
			*regT |= (1 << ((gpio_num % 16) * 2 + 1));
		}
		if(function == GPIO_AS_AF3)
		{

			//*regT &= ~(11 << ((gpio_num % 16) * 2));
			*regT |= ((1 << ((gpio_num % 16) * 2)) | (1 << ((gpio_num % 16) * 2 + 1)));
		}
		return;
	}
	if(gpio_num < 32)
	{
		regT = (volatile int *)GAFR0_U;
		if(function == GPIO_AS_GPIO)
		{

			*regT &= ~((1 << ((gpio_num % 16) * 2)) | (1 << ((gpio_num % 16) * 2 + 1)));
			//*regT |= (11 << ((gpio_num % 16) * 2));
		}
		if(function == GPIO_AS_AF1)
		{

			*regT &= ~(1 << ((gpio_num % 16) * 2 + 1));
			*regT |= (1 << ((gpio_num % 16) * 2));
		}
		if(function == GPIO_AS_AF2)
		{

			*regT &= ~(1 << ((gpio_num % 16) * 2));
			*regT |= (1 << ((gpio_num % 16) * 2 + 1));
		}
		if(function == GPIO_AS_AF3)
		{

			//*regT &= ~(11 << ((gpio_num % 16) * 2));
			*regT |= ((1 << ((gpio_num % 16) * 2)) | (1 << ((gpio_num % 16) * 2 + 1)));
		}
		return;
	}
	if(gpio_num < 48)
	{
		regT = (volatile int *)GAFR1_L;
		if(function == GPIO_AS_GPIO)
		{

			*regT &= ~((1 << ((gpio_num % 16) * 2)) | (1 << ((gpio_num % 16) * 2 + 1)));
			//*regT |= (11 << ((gpio_num % 16) * 2));
		}
		if(function == GPIO_AS_AF1)
		{

			*regT &= ~(1 << ((gpio_num % 16) * 2 + 1));
			*regT |= (1 << ((gpio_num % 16) * 2));
		}
		if(function == GPIO_AS_AF2)
		{

			*regT &= ~(1 << ((gpio_num % 16) * 2));
			*regT |= (1 << ((gpio_num % 16) * 2 + 1));
		}
		if(function == GPIO_AS_AF3)
		{

			//*regT &= ~(11 << ((gpio_num % 16) * 2));
			*regT |= ((1 << ((gpio_num % 16) * 2)) | (1 << ((gpio_num % 16) * 2 + 1)));
		}
		return;
	}
	if(gpio_num < 64)
	{
		regT = (volatile int *)GAFR1_U;
		if(function == GPIO_AS_GPIO)
		{

			*regT &= ~((1 << ((gpio_num % 16) * 2)) | (1 << ((gpio_num % 16) * 2 + 1)));
			//*regT |= (11 << ((gpio_num % 16) * 2));
		}
		if(function == GPIO_AS_AF1)
		{

			*regT &= ~(1 << ((gpio_num % 16) * 2 + 1));
			*regT |= (1 << ((gpio_num % 16) * 2));
		}
		if(function == GPIO_AS_AF2)
		{

			*regT &= ~(1 << ((gpio_num % 16) * 2));
			*regT |= (1 << ((gpio_num % 16) * 2 + 1));
		}
		if(function == GPIO_AS_AF3)
		{

			//*regT &= ~(11 << ((gpio_num % 16) * 2));
			*regT |= ((1 << ((gpio_num % 16) * 2)) | (1 << ((gpio_num % 16) * 2 + 1)));
		}
		return;
	}
	if(gpio_num < 80)
	{
		regT = (volatile int *)GAFR2_L;
		if(function == GPIO_AS_GPIO)
		{

			*regT &= ~((1 << ((gpio_num % 16) * 2)) | (1 << ((gpio_num % 16) * 2 + 1)));
			//*regT |= (11 << ((gpio_num % 16) * 2));
		}
		if(function == GPIO_AS_AF1)
		{

			*regT &= ~(1 << ((gpio_num % 16) * 2 + 1));
			*regT |= (1 << ((gpio_num % 16) * 2));
		}
		if(function == GPIO_AS_AF2)
		{

			*regT &= ~(1 << ((gpio_num % 16) * 2));
			*regT |= (1 << ((gpio_num % 16) * 2 + 1));
		}
		if(function == GPIO_AS_AF3)
		{

			//*regT &= ~(11 << ((gpio_num % 16) * 2));
			*regT |= ((1 << ((gpio_num % 16) * 2)) | (1 << ((gpio_num % 16) * 2 + 1)));
		}
		return;
	}
	if(gpio_num < 96)
	{
		regT = (volatile int *)GAFR2_U;
		if(function == GPIO_AS_GPIO)
		{

			*regT &= ~((1 << ((gpio_num % 16) * 2)) | (1 << ((gpio_num % 16) * 2 + 1)));
			//*regT |= (11 << ((gpio_num % 16) * 2));
		}
		if(function == GPIO_AS_AF1)
		{

			*regT &= ~(1 << ((gpio_num % 16) * 2 + 1));
			*regT |= (1 << ((gpio_num % 16) * 2));
		}
		if(function == GPIO_AS_AF2)
		{

			*regT &= ~(1 << ((gpio_num % 16) * 2));
			*regT |= (1 << ((gpio_num % 16) * 2 + 1));
		}
		if(function == GPIO_AS_AF3)
		{

			//*regT &= ~(11 << ((gpio_num % 16) * 2));
			*regT |= ((1 << ((gpio_num % 16) * 2)) | (1 << ((gpio_num % 16) * 2 + 1)));
		}
		return;
	}
	if(gpio_num < 112)
	{
		regT = (volatile int *)GAFR3_L;
		if(function == GPIO_AS_GPIO)
		{

			*regT &= ~((1 << ((gpio_num % 16) * 2)) | (1 << ((gpio_num % 16) * 2 + 1)));
			//*regT |= (11 << ((gpio_num % 16) * 2));
		}
		if(function == GPIO_AS_AF1)
		{

			*regT &= ~(1 << ((gpio_num % 16) * 2 + 1));
			*regT |= (1 << ((gpio_num % 16) * 2));
		}
		if(function == GPIO_AS_AF2)
		{

			*regT &= ~(1 << ((gpio_num % 16) * 2));
			*regT |= (1 << ((gpio_num % 16) * 2 + 1));
		}
		if(function == GPIO_AS_AF3)
		{

			//*regT &= ~(11 << ((gpio_num % 16) * 2));
			*regT |= ((1 << ((gpio_num % 16) * 2)) | (1 << ((gpio_num % 16) * 2 + 1)));
		}
		return;
	}
	if(gpio_num <= 120)
	{
		regT = (volatile int *)GAFR3_U;
		if(function == GPIO_AS_GPIO)
		{

			*regT &= ~((1 << ((gpio_num % 16) * 2)) | (1 << ((gpio_num % 16) * 2 + 1)));
			//*regT |= (11 << ((gpio_num % 16) * 2));
		}
		if(function == GPIO_AS_AF1)
		{

			*regT &= ~(1 << ((gpio_num % 16) * 2 + 1));
			*regT |= (1 << ((gpio_num % 16) * 2));
		}
		if(function == GPIO_AS_AF2)
		{

			*regT &= ~(1 << ((gpio_num % 16) * 2));
			*regT |= (1 << ((gpio_num % 16) * 2 + 1));
		}
		if(function == GPIO_AS_AF3)
		{

			//*regT &= ~(11 << ((gpio_num % 16) * 2));
			*regT |= ((1 << ((gpio_num % 16) * 2)) | (1 << ((gpio_num % 16) * 2 + 1)));
		}
		return;
	}

}
void xs_clrgpio_EDR(int gpio_num)
{
	volatile int *regT;

	if(gpio_num < 32)
	{
		regT = (volatile int *)GEDR0;
		*regT |= (1 << (gpio_num % 32));
		return;
	}
	if(gpio_num < 64)
	{
		regT = (volatile int *)GEDR1;
		*regT |= (1 << (gpio_num % 32));
		return;
	}
	if(gpio_num < 96)
	{
		regT = (volatile int *)GEDR2;
		*regT |= (1 << (gpio_num % 32));
		return;
	}
	if(gpio_num <= 120)
	{
		regT = (volatile int *)GEDR3;
		*regT |= (1 << (gpio_num % 32));
		return;
	}
}

int xs_getgpio_inLEV(int gpio_num)
{
	volatile int *regT;

	if(gpio_num < 32)
	{
		regT = (volatile int *)GPLR0;
		if(*regT & (1 << (gpio_num % 32)))
			return GPIO_HIGH;
		else
			return GPIO_LOW;
	}
	if(gpio_num < 64)
	{
		regT = (volatile int *)GPLR1;
		if(*regT & (1 << (gpio_num % 32)))
			return GPIO_HIGH;
		else
			return GPIO_LOW;
	}
	if(gpio_num < 96)
	{
		regT = (volatile int *)GPLR2;
		if(*regT & (1 << (gpio_num % 32)))
			return GPIO_HIGH;
		else
			return GPIO_LOW;
	}
	if(gpio_num <= 120)
	{
		regT = (volatile int *)GPLR3;
		if(*regT & (1 << (gpio_num % 32)))
			return GPIO_HIGH;
		else
			return GPIO_LOW;
	}
	return 0;
}
int xs_getgpio_EDR(int gpio_num)
{
	volatile int *regT;

	if(gpio_num < 32)
	{
		regT = (volatile int *)GEDR0;
		if(*regT & (1 << (gpio_num % 32)))
			return GPIO_EDGE;
		else
			return GPIO_NOEDGE;
	}
	if(gpio_num < 64)
	{
		regT = (volatile int *)GEDR1;
		if(*regT & (1 << (gpio_num % 32)))
			return GPIO_EDGE;
		else
			return GPIO_NOEDGE;
	}
	if(gpio_num < 96)
	{
		regT = (volatile int *)GEDR2;
		if(*regT & (1 << (gpio_num % 32)))
			return GPIO_EDGE;
		else
			return GPIO_NOEDGE;
	}
	if(gpio_num <= 120)
	{
		regT = (volatile int *)GEDR3;
		if(*regT & (1 << (gpio_num % 32)))
			return GPIO_EDGE;
		else
			return GPIO_NOEDGE;
	}
	return 0;
}
